package com.rrd.hive.udf;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.hadoop.hive.ql.exec.UDF;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class JsonConversion extends UDF {
    private  Map<String,String> resultMap = new HashMap<>();

    public Map<String,String> evaluate(String args) {
        if (args.length() < 1){
            return null;
        }else{
            String str = formatStr(args);
            JSONObject jsonObject = JSON.parseObject(str);
            parseJsonToMap("", jsonObject);
            return resultMap;
        }
    }

    private String formatStr(String str){
        str = str.replaceAll("\\s+","")
                .replaceAll("\\\\n|\\\\", "")
                .replaceAll("\"\"\\{|\"\\{", "{")
                .replaceAll("}\"\"|}\\\"", "}")
                .replaceAll("\"\\[\\{", "[{")
                .replaceAll("}]\"", "}]")
                .replaceAll("\"\\[\"", "[")
                .replaceAll("\"]\"", "\"]")
                .replaceAll("\"\"","\"")
                .replaceAll(":\",",":\"\",")
                .replaceAll(":\"]",":\"\"]")
                .replaceAll(":\"}",":\"\"}")
                .trim();

        if(!str.startsWith("{")){
            str = "{"+str+"}";
        }
        return str;
    }
    private  void parseJsonToMap(String key, Object object){
        if(object instanceof  Map){
            Map<String,Object> mapObject = (Map<String, Object>) object;
            Set<Map.Entry<String, Object>> entries = mapObject.entrySet();
            for(Map.Entry<String,Object> entry : entries){
                String curentKey = null;
                if(key.isEmpty()){
                    curentKey = entry.getKey();
                }else{
                    curentKey = key+"_"+entry.getKey();
                }
                Object currentValue = entry.getValue();
                parseJsonToMap(curentKey,currentValue);

            }
        }else {
            if(object != null){
                resultMap.put(key,object.toString());
            }else {
                resultMap.put(key,null);
            }
        }
    }

}
